/********************************************
* Copyrigt (C) rumi
* Module: drv_iic.c
*********************************************/
#include "drv_iic.h"
/**************************Init Area*********************************/


/*******************************************************************/
static void i2c_Delay(iic_Node *iic)
{
	for (uint8_t i = 0; i < iic->SpeedDelay; i++);
}

void i2c_Start(iic_Node *iic)
{
	Drv_IO_Control(iic->SDA,E_PIN_WRITE,high);
	Drv_IO_Control(iic->SCL,E_PIN_WRITE,high);
	i2c_Delay(iic);
	Drv_IO_Control(iic->SDA,E_PIN_WRITE,low);
	i2c_Delay(iic);
	Drv_IO_Control(iic->SCL,E_PIN_WRITE,low);
	i2c_Delay(iic);
}

void iO_Start(iic_Node *iic)
{
	Drv_IO_Control(iic->SDA,E_PIN_WRITE,low);
	Drv_IO_Control(iic->SCL,E_PIN_WRITE,low);
}


void i2c_Stop(iic_Node *iic)
{
	Drv_IO_Control(iic->SDA,E_PIN_WRITE,low);
	Drv_IO_Control(iic->SCL,E_PIN_WRITE,high);
	i2c_Delay(iic);
	Drv_IO_Control(iic->SDA,E_PIN_WRITE,high);
}


 
void i2c_SendByte(iic_Node *iic,uint8_t ucByte)
{
	uint8_t i;
	for (i = 0; i < 8; i++)
	{
		if (ucByte & 0x80)
		{
			Drv_IO_Control(iic->SDA,E_PIN_WRITE,high);
		}else{
			Drv_IO_Control(iic->SDA,E_PIN_WRITE,low);
		}
		i2c_Delay(iic);
		Drv_IO_Control(iic->SCL,E_PIN_WRITE,high);
		i2c_Delay(iic);
		Drv_IO_Control(iic->SCL,E_PIN_WRITE,low);
		if (i == 7)
		{
			Drv_IO_Control(iic->SDA,E_PIN_WRITE,high); 
		}
		ucByte <<= 1;	
		i2c_Delay(iic);
	}
}


uint8_t i2c_ReadByte(iic_Node *iic)
{
	uint8_t i;
	uint8_t value;
	value = 0;
	for (i = 0; i < 8; i++){
		value <<= 1;
		Drv_IO_Control(iic->SCL,E_PIN_WRITE,high);
		i2c_Delay(iic);
		
		if(Drv_IO_Control(iic->SDA,E_PIN_READ,0)){
			value++;
		}
		Drv_IO_Control(iic->SCL,E_PIN_WRITE,low);
		i2c_Delay(iic);
	}
	return value;
}


uint8_t i2c_WaitAck(iic_Node *iic)
{
	uint8_t re;
	Drv_IO_Control(iic->SDA,E_PIN_WRITE,high);	
	i2c_Delay(iic);
	Drv_IO_Control(iic->SCL,E_PIN_WRITE,high);	
	i2c_Delay(iic);
	if(Drv_IO_Control(iic->SDA,E_PIN_READ,0))
	{	
		re = 1;
	}
	else
	{
		re = 0;
	}
	Drv_IO_Control(iic->SCL,E_PIN_WRITE,low);
	i2c_Delay(iic);
	return re;
}


void i2c_Ack(iic_Node *iic)
{
	Drv_IO_Control(iic->SDA,E_PIN_WRITE,low);
	i2c_Delay(iic);
	Drv_IO_Control(iic->SCL,E_PIN_WRITE,high);
	i2c_Delay(iic);
	Drv_IO_Control(iic->SCL,E_PIN_WRITE,low);
	i2c_Delay(iic);
	Drv_IO_Control(iic->SDA,E_PIN_WRITE,high);
}


void i2c_NAck(iic_Node *iic)
{
	Drv_IO_Control(iic->SDA,E_PIN_WRITE,high);
	i2c_Delay(iic);
	Drv_IO_Control(iic->SCL,E_PIN_WRITE,high);
	i2c_Delay(iic);
	Drv_IO_Control(iic->SCL,E_PIN_WRITE,low);
	i2c_Delay(iic);
}
 

uint8_t i2c_CheckDevice(iic_Node *iic,uint8_t _Address)
{
	uint8_t ucAck = 1;
	i2c_Start(iic);		
	i2c_SendByte(iic,_Address | I2C_WR);
	ucAck = i2c_WaitAck(iic);
 
	i2c_Stop(iic);		
 
	return ucAck;
}


uint8_t iic_Device_CheckOK(iic_Node *iic,uint8_t addr)
{
	if (i2c_CheckDevice(iic,addr) == 0){
		return 1;
	}else{
		i2c_Stop(iic);
		return 0;
	}
}

void iic_Write_Byte(iic_Node *iic,uint8_t addr,uint8_t regster_addr,uint8_t value)
{
	i2c_Start(iic);
	i2c_SendByte(iic,addr | I2C_WR);
	i2c_WaitAck(iic);
	i2c_SendByte(iic,regster_addr);
	i2c_WaitAck(iic);
	i2c_SendByte(iic,value);
	i2c_WaitAck(iic);
	i2c_Stop(iic);
}

uint8_t Drv_IIC_WriteByte(iic_Node *iic,uint8_t addr,uint8_t regster_addr,uint8_t *pBuffer,uint8_t Length)
{
	if(Length > 8)
	{
	}
	i2c_Start(iic);
	addr = addr << 1;
	i2c_SendByte(iic,addr | I2C_WR);
	if (i2c_WaitAck(iic) != 0)
	{
		goto cmd_fail;	
	}
	i2c_SendByte(iic,regster_addr);
	if (i2c_WaitAck(iic) != 0)
	{
		goto cmd_fail;	
	}
	
	for(uint8_t i=0; i<Length; i++)
	{
		i2c_SendByte(iic,pBuffer[i]);
		if (i2c_WaitAck(iic) != 0)
		{
			goto cmd_fail;	
		}
	}
	i2c_Stop(iic);
cmd_fail:
	i2c_Stop(iic);
	return 0;
}

uint8_t Drv_IIC_WriteReg(iic_Node *iic,uint8_t addr,uint8_t regster_addr,uint8_t Data)
{
	return Drv_IIC_WriteByte(iic,addr,regster_addr,&Data,1);
}

uint8_t Drv_IIC_ReadByte( iic_Node *iic,uint8_t addr,uint16_t _usAddress,uint8_t *buff,uint8_t _usSize)
{
	uint8_t i = 0;
 
	i2c_Start(iic);	
	addr = addr << 1;
	i2c_SendByte(iic,addr | I2C_WR);
	if (i2c_WaitAck(iic) != 0)
	{
		goto cmd_fail;	
	}
	i2c_SendByte(iic,(uint8_t)_usAddress);
	if (i2c_WaitAck(iic) != 0)
	{
		goto cmd_fail;
	}
	i2c_Delay(iic);
	i2c_Delay(iic);
	i2c_Start(iic);
	i2c_SendByte(iic,addr | I2C_RD);

	if (i2c_WaitAck(iic) != 0)
	{
		goto cmd_fail;
	}
	for (i = 0; i < _usSize; i++)
	{
		buff[i] = i2c_ReadByte(iic);
 
		if (i != _usSize - 1)
		{
			i2c_Ack(iic);
		}
		else
		{
			i2c_NAck(iic);
		}
	}
	i2c_Stop(iic);
	return 1;
cmd_fail:
	i2c_Stop(iic);
	return 0;
}
 


uint16_t Drv_IIC_ReadTwoByte( iic_Node *iic,uint8_t addr,uint16_t _usAddress)
{
	uint16_t temp = 0;
	i2c_Start(iic);	
  addr = addr << 1;
	i2c_SendByte(iic,addr | I2C_WR);
	if (i2c_WaitAck(iic) != 0)
	{
		goto cmd_fail;
	}
	i2c_SendByte(iic,(uint8_t)_usAddress);
	if (i2c_WaitAck(iic) != 0)
	{
		goto cmd_fail;
	}
	i2c_Start(iic);	
	i2c_SendByte(iic,addr | I2C_RD);
	if (i2c_WaitAck(iic) != 0)
	{
		goto cmd_fail;
	}
	temp =(i2c_ReadByte(iic) << 8);
	i2c_Ack(iic);
	temp |=(i2c_ReadByte(iic) & 0xff);
	i2c_NAck(iic);
	i2c_Stop(iic);
	return temp;
cmd_fail: 
	i2c_Stop(iic);
	return 0;
}
 


uint8_t Drv_IIC_Read_Reg( iic_Node *iic,uint8_t addr,uint16_t _usAddress)
{
	uint8_t temp = 0;
	i2c_Start(iic);	
	addr = addr << 1;
	i2c_SendByte(iic,addr | I2C_WR);
	if (i2c_WaitAck(iic) != 0)
	{
		goto cmd_fail;
	}
	i2c_SendByte(iic,(uint8_t)_usAddress);
	if (i2c_WaitAck(iic) != 0)
	{
		goto cmd_fail;
	}
	i2c_Start(iic);
	i2c_SendByte(iic,addr | I2C_RD);
	if (i2c_WaitAck(iic) != 0)
	{
		goto cmd_fail;
	}
	temp =i2c_ReadByte(iic)&0xff;
	i2c_NAck(iic);
	i2c_Stop(iic);
	return temp;
cmd_fail:
	i2c_Stop(iic);
	return 0;
}
 
/*************End of file*******************/

